package com.cardone.platform.usercenter.util;

import com.cardone.context.ContextHolder;
import com.cardone.platform.usercenter.dto.UserDto;
import com.cardone.platform.usercenter.service.UserService;
import com.cardone.security.token.dto.TokenDto;
import com.cardone.security.token.util.TokenUtils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;

/**
 * Created by Administrator on 2014/11/10.
 */
@Slf4j
public class UserUtils {
    @Setter
    private static UserDto devUser;

    public static UserDto find() {
        return find(false);
    }

    public static UserDto findForNotCache(String tokenKey) {
        return findByToken(tokenKey, true);
    }

    public static UserDto findForNotCache() {
        return find(true);
    }

    public static UserDto find(String tokenKey) {
        return findByToken(tokenKey, false);
    }

    /**
     * 获取用户标识
     *
     * @return
     */
    public static String readId() {
        try {
            String tokenKey = TokenUtils.getTokenKey();

            if (StringUtils.isNotBlank(tokenKey)) {
                String id = readId(tokenKey);

                if (StringUtils.isNotBlank(id)) {
                    return id;
                }
            }

            UserDto user = (UserDto) SecurityUtils.getSubject().getPrincipal();

            if (user != null) {
                return user.getId();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    /**
     * 获取用户标识
     *
     * @param tokenKey
     * @return
     */
    public static String readId(String tokenKey) {
        try {
            TokenDto token = TokenUtils.get(tokenKey);

            if ((token != null) && (token.getId() != null)) {
                if (token.getId() instanceof String) {
                    return token.getId().toString();
                } else if (token.getId() instanceof UserDto) {
                    UserDto user = (UserDto) token.getId();

                    if (user != null) {
                        return user.getId();
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    private static UserDto find(boolean notCache) {
        try {
            UserDto user = (UserDto) SecurityUtils.getSubject().getPrincipal();

            if (user != null) {
                if (!notCache) {
                    return user;
                }

                user = ContextHolder.getBean(UserService.class).findById(user.getId());

                if (user != null) {
                    return user;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        try {
            String tokenKey = TokenUtils.getTokenKey();

            return findByToken(tokenKey, notCache);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        if (devUser != null) {
            return devUser;
        }

        return new UserDto();
    }

    private static UserDto findByToken(String tokenKey, boolean notCache) {
        try {
            TokenDto token = TokenUtils.get(tokenKey);

            if ((token != null) && (token.getId() != null)) {
                UserDto user = null;

                if (token.getId() instanceof String) {
                    String id = token.getId().toString();

                    user = ContextHolder.getBean(UserService.class).findById(id);
                } else if (token.getId() instanceof UserDto) {
                    user = (UserDto) token.getId();

                    if (user != null) {
                        if (!notCache) {
                            return user;
                        }

                        user = ContextHolder.getBean(UserService.class).findById(user.getId());
                    }
                }

                if (user != null) {
                    return user;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        if (devUser != null) {
            return devUser;
        }

        return new UserDto();
    }
}
